{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import win32com.client as win32\n",
    "\n",
    "fname = r\"C:\\Users\\zhangbohang\\Projects\\TableSense\\test_data\\1_Book1.xls\"\n",
    "excel = win32.gencache.EnsureDispatch('Excel.Application')\n",
    "wb = excel.Workbooks.Open(fname)\n",
    "\n",
    "wb.SaveAs(fname+\"x\", FileFormat = 51)    #FileFormat = 51 is for .xlsx extension\n",
    "wb.Close()                               #FileFormat = 56 is for .xls extension\n",
    "excel.Application.Quit()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torchvision\n",
    "from torchvision.models.detection.faster_rcnn import FastRCNNPredictor\n",
    "\n",
    "# load a model pre-trained on COCO\n",
    "model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)\n",
    "\n",
    "# replace the classifier with a new one, that has\n",
    "# num_classes which is user-defined\n",
    "num_classes = 2  # 1 class (person) + background\n",
    "# get number of input features for the classifier\n",
    "in_features = model.roi_heads.box_predictor.cls_score.in_features\n",
    "# replace the pre-trained head with a new one\n",
    "model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torchvision\n",
    "from torchvision.models.detection import FasterRCNN\n",
    "from torchvision.models.detection.rpn import AnchorGenerator\n",
    "\n",
    "# load a pre-trained model for classification and return\n",
    "# only the features\n",
    "backbone = torchvision.models.mobilenet_v2(pretrained=True).features\n",
    "# FasterRCNN needs to know the number of\n",
    "# output channels in a backbone. For mobilenet_v2, it's 1280\n",
    "# so we need to add it here\n",
    "backbone.out_channels = 1280\n",
    "\n",
    "# let's make the RPN generate 5 x 3 anchors per spatial\n",
    "# location, with 5 different sizes and 3 different aspect\n",
    "# ratios. We have a Tuple[Tuple[int]] because each feature\n",
    "# map could potentially have different sizes and\n",
    "# aspect ratios\n",
    "anchor_generator = AnchorGenerator(sizes=((32, 64, 128, 256, 512), ),\n",
    "                                   aspect_ratios=((0.5, 1.0, 2.0), ))\n",
    "\n",
    "# let's define what are the feature maps that we will\n",
    "# use to perform the region of interest cropping, as well as\n",
    "# the size of the crop after rescaling.\n",
    "# if your backbone returns a Tensor, featmap_names is expected to\n",
    "# be [0]. More generally, the backbone should return an\n",
    "# OrderedDict[Tensor], and in featmap_names you can choose which\n",
    "# feature maps to use.\n",
    "roi_pooler = torchvision.ops.MultiScaleRoIAlign(featmap_names=['0'],\n",
    "                                                output_size=7,\n",
    "                                                sampling_ratio=2)\n",
    "\n",
    "# put the pieces together inside a FasterRCNN model\n",
    "model = FasterRCNN(backbone,\n",
    "                   num_classes=2,\n",
    "                   rpn_anchor_generator=anchor_generator,\n",
    "                   box_roi_pool=roi_pooler)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)\n",
    "dataset = PennFudanDataset('PennFudanPed', get_transform(train=True))\n",
    "data_loader = torch.utils.data.DataLoader(dataset,\n",
    "                                          batch_size=2,\n",
    "                                          shuffle=True,\n",
    "                                          num_workers=4,\n",
    "                                          collate_fn=utils.collate_fn)\n",
    "# For Training\n",
    "images, targets = next(iter(data_loader))\n",
    "images = list(image for image in images)\n",
    "targets = [{k: v for k, v in t.items()} for t in targets]\n",
    "output = model(images, targets)  # Returns losses and detections\n",
    "# For inference\n",
    "model.eval()\n",
    "x = [torch.rand(3, 300, 400), torch.rand(3, 500, 400)]\n",
    "predictions = model(x)  # Returns predictions\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from engine import train_one_epoch, evaluate\n",
    "import utils\n",
    "\n",
    "\n",
    "def main():\n",
    "    # train on the GPU or on the CPU, if a GPU is not available\n",
    "    device = torch.device(\n",
    "        'cuda') if torch.cuda.is_available() else torch.device('cpu')\n",
    "\n",
    "    # our dataset has two classes only - background and person\n",
    "    num_classes = 2\n",
    "    # use our dataset and defined transformations\n",
    "    dataset = PennFudanDataset('PennFudanPed', get_transform(train=True))\n",
    "    dataset_test = PennFudanDataset('PennFudanPed', get_transform(train=False))\n",
    "\n",
    "    # split the dataset in train and test set\n",
    "    indices = torch.randperm(len(dataset)).tolist()\n",
    "    dataset = torch.utils.data.Subset(dataset, indices[:-50])\n",
    "    dataset_test = torch.utils.data.Subset(dataset_test, indices[-50:])\n",
    "\n",
    "    # define training and validation data loaders\n",
    "    data_loader = torch.utils.data.DataLoader(dataset,\n",
    "                                              batch_size=2,\n",
    "                                              shuffle=True,\n",
    "                                              num_workers=4,\n",
    "                                              collate_fn=utils.collate_fn)\n",
    "\n",
    "    data_loader_test = torch.utils.data.DataLoader(dataset_test,\n",
    "                                                   batch_size=1,\n",
    "                                                   shuffle=False,\n",
    "                                                   num_workers=4,\n",
    "                                                   collate_fn=utils.collate_fn)\n",
    "\n",
    "    # get the model using our helper function\n",
    "    model = get_model_instance_segmentation(num_classes)\n",
    "\n",
    "    # move model to the right device\n",
    "    model.to(device)\n",
    "\n",
    "    # construct an optimizer\n",
    "    params = [p for p in model.parameters() if p.requires_grad]\n",
    "    optimizer = torch.optim.SGD(params,\n",
    "                                lr=0.005,\n",
    "                                momentum=0.9,\n",
    "                                weight_decay=0.0005)\n",
    "    # and a learning rate scheduler\n",
    "    lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer,\n",
    "                                                   step_size=3,\n",
    "                                                   gamma=0.1)\n",
    "\n",
    "    # let's train it for 10 epochs\n",
    "    num_epochs = 10\n",
    "\n",
    "    for epoch in range(num_epochs):\n",
    "        # train for one epoch, printing every 10 iterations\n",
    "        train_one_epoch(model,\n",
    "                        optimizer,\n",
    "                        data_loader,\n",
    "                        device,\n",
    "                        epoch,\n",
    "                        print_freq=10)\n",
    "        # update the learning rate\n",
    "        lr_scheduler.step()\n",
    "        # evaluate on the test dataset\n",
    "        evaluate(model, data_loader_test, device=device)\n",
    "\n",
    "    print(\"That's it!\")"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "2733babc0711d44ce5efad954458b35776c6433580c3fe472215f0f10b3611a5"
  },
  "kernelspec": {
   "display_name": "Python 3.7.8 64-bit ('venv': venv)",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.8"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
